#include "hdl_serial_driver.h"

struct _hdl_serial_str_cmp *str_cmp = usmart_nametab;
BOOL hdl_cmd_debug_flag = FALSE;
int8_t hdl_timer4_init(uint32_t ms)
{
    TIM_TimeBaseInitTypeDef     TIM_TimeBaseStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
    TIM_TimeBaseStructure.TIM_ClockDivision    =   TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode      =   TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period           =   ms-1;
    TIM_TimeBaseStructure.TIM_Prescaler        =   36000-1;
    TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
    USR_NVIC_Config(TIM4_IRQn,0,0);
    TIM_Cmd(TIM4,ENABLE);
    hdl_cmd_debug_flag = FALSE;
    return SUCCESS;
}

int8_t hdl_timer4_deinit(void)
{
    TIM_Cmd(TIM4,DISABLE);
    return SUCCESS;
}

void TIM4_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)
    {
        usmart_dev.usmart_scan();
    }
    TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}

int hdl_serial_string_sep(char *cmd)
{
    char *token = NULL;
    char *param = NULL;
    char buf[LOG_SERVICE_BUFLEN];
    char *copy = buf;
    uint8_t cmd_list_len = 0;
    if(*cmd == NULL)
        return -1;
    str_cmp = usmart_nametab;
    cmd_list_len = usmart_dev.func_num();
    strncpy(copy, cmd, LOG_SERVICE_BUFLEN - 1);
    token = strtok(copy, " ");
    param = strtok(NULL, "\0");
    DBG_MSG("token:%s\r\n",token);
    if(strcmp(token,"help") == 0)
    {
        DBG_MSG("=================================\r\n");
        DBG_MSG("function list:\r\n");
        for (size_t i = 0; i < cmd_list_len; i++)
        {
            DBG_MSG("%d:%s\r\n",i,str_cmp->name);
            str_cmp++;
        }
        DBG_MSG("=================================\r\n");
        return -2;
    }
    for (int i = 0; i < cmd_list_len; i++)
    {
        if(strcmp(token,str_cmp->name) == 0)
        {
            DBG_MSG("name->%s success\r\n",str_cmp->name);
            str_cmp->func(param);
            usmart_dev.API_Match_flag = TRUE;
            break;
        }
        str_cmp++;
    }
    if(usmart_dev.API_Match_flag == FALSE)
    {
        DBG_MSG("=================================\r\n");
        DBG_MSG("Unknown cmd:%s\r\n",token);
        DBG_MSG("KEY \"help\" for more infomation?\r\n");
        DBG_MSG("=================================\r\n");
    }
    else
    {
        usmart_dev.API_Match_flag = FALSE;
    }
    // DBG_MSG("cmd->%s success\r\n",str_cmp->name);
    return SUCCESS;
}

uint8_t hdl_usmart_parse_param(char *buf, char **argv)
{
    int argc = 1;
    char str_buf[LOG_SERVICE_BUFLEN];
    memset(str_buf, 0, LOG_SERVICE_BUFLEN);
    int str_count = 0;
    int buf_cnt = 0;
    static char temp_buf[LOG_SERVICE_BUFLEN];
    char *buf_pos = temp_buf;
    memset(temp_buf, 0, sizeof(temp_buf));
    if (buf == NULL) 
    {
        goto exit;
    }
    strncpy(temp_buf, buf, LOG_SERVICE_BUFLEN - 1);
    while ((argc < MAX_ARGC) && (*buf_pos != '\0'))
    {
        while ((*buf_pos == ' ') || (*buf_pos == '[') || (*buf_pos == ']'))
        {
            if ((*buf_pos == ' ') && (*(buf_pos + 1) == ' '))
            {
                argv[argc] = NULL;
                argc++;
            }
            *buf_pos = '\0';
            buf_pos++;
        }
        if (*buf_pos == '\0') 
        {
            break;
        }
        else if (*buf_pos == '"') 
        {
            memset(str_buf, '\0', LOG_SERVICE_BUFLEN);
            str_count = 0;
            buf_cnt = 0;
            *buf_pos = '\0';
            buf_pos ++;
            if (*buf_pos == '\0') 
            {
                break;
            }
            argv[argc] = buf_pos;
            while ((*buf_pos != '"') && (*buf_pos != '\0'))
            {
                if (*buf_pos == '\\')
                {
                    buf_pos ++;
                    buf_cnt++;
                }
                str_buf[str_count] = *buf_pos;
                str_count++;
                buf_cnt++;
                buf_pos ++;
            }
            *buf_pos = '\0';
            memcpy(buf_pos - buf_cnt, str_buf, buf_cnt);
        }
        else
        {
            argv[argc] = buf_pos;
        }
        argc++;
        buf_pos++;
        while ((*buf_pos != ' ') && (*buf_pos != '\0') && (*buf_pos != '[') && (*buf_pos != ']'))
        {
            buf_pos++;
        }
    }
    if(hdl_cmd_debug_flag == TRUE)
    {
        for(uint8_t i=0;i<argc;i++)
        {
            DBG_MSG("argv[%d]:%s\r\n",i,argv[i]);
        }
    }
    exit:
        return argc;
}

struct _hal_serial g_hdl_usart_if =
{
    .serial_init = hdl_timer4_init,
    .serial_deinit = hdl_timer4_deinit,
    .serial_str_cmp = hdl_serial_string_sep,
    .serial_parse_parm = hdl_usmart_parse_param,
};



